package controller;

import entity.FileSystem;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @program: redis-fastdfs
 * @Description: 上传文件控制层
 * @author: sufulu
 * @version: 1.0.0
 * @create: 2021-02-03 23:04
 * @PackageName: controller
 * @ClassName: FileController.java
 **/
@RestController
public class FileController {

    @Autowired
    private Redisson redisson;

    @RequestMapping("upload")
    public FileSystem upload(MultipartHttpServletRequest request) throws Exception {
        //通过redisson获得锁
        RLock rLock = redisson.getLock("FILE_UPLOAD");
        //上锁过期时间为60s 由于是上传的视频，让锁的过期时间长一些
        rLock.lock(60, TimeUnit.SECONDS);
        try {
            return getFileSystem(request);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放锁
            rLock.unlock();
        }
        return new FileSystem();
    }

    private FileSystem getFileSystem(MultipartHttpServletRequest request) throws IOException, MyException {
        FileSystem fileSystem = new FileSystem();

        //1. 先把文件保存到web服务器上
        //从页面请求中获取，拿上传的文件对象
        MultipartFile file = request.getFile("file");
        //从文件对象中获取文件的原始名称
        String oldFilename = file.getOriginalFilename();
        //获取后缀名 通过字符串截取获得
        String suffixName = oldFilename.substring(oldFilename.lastIndexOf(".") + 1);
        //重新生成文件名，避免文件同名而覆盖
        String newFileName = UUID.randomUUID().toString() + "." + suffixName;
        //创建web服务器保存文件的目录
        File webSaveFile = new File("/Users/prim/Downloads/" + newFileName);
        //将路径转换成文件
        file.transferTo(webSaveFile);
        //获取服务器的绝对路径
        String webPath = webSaveFile.getAbsolutePath();

        //2. 再从web服务上将文件上传到fastDFS上
        ClientGlobal.initByProperties("config/fastdfs-client.properties");
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageServer storageServer = null;
        StorageClient1 client1 = new StorageClient1(trackerServer, storageServer);
        NameValuePair[] nameValuePairs = new NameValuePair[1];
        nameValuePairs[0] = new NameValuePair("fileName", oldFilename);
        String fileId = client1.upload_file1(webPath, suffixName, nameValuePairs);
        trackerServer.close();

        //3. 封装返回的数据对象
        fileSystem.setFileId(fileId);
        fileSystem.setFileName(oldFilename);
        fileSystem.setFilePath(fileId);//已经上传到fastDFS上通过fileId来访问图片
        System.out.println(fileSystem);
        return fileSystem;
    }

    @Bean
    public Redisson redisson() {
        Config config = new Config();
//        config.useSingleServer().setAddress("redis://172.16.150.131:6379").setDatabase(0);
        //使用Redis集群-主从复制
        config.useMasterSlaveServers()
                .setMasterAddress("redis://172.16.150.131:6379")
                .addSlaveAddress("redis://172.16.150.130:6379", "redis://172.16.150.132:6379");
        //redis 集群模式
//        config.useClusterServers().setScanInterval(2000)
//                .addNodeAddress("redis://172.16.150.131:6379", "redis://172.16.150.130:6379", "redis://172.16.150.132:6379");
        return (Redisson) Redisson.create(config);
    }
}
